9.IDA

您所在的位置:网站首页 ida 修改汇编 9.IDA

9.IDA

2024-02-03 13:30| 来源: 网络整理| 查看: 265

1.重新设置函数类型

写一个简单的代码做测试:

[cpp]  view plain  copy int fun(int a, double b)   {       return 0;   }      int _tmain(int argc, _TCHAR* argv[])   {       int c = fun(1, 2);       return 0;   }   release生成,去掉pdb,由于fun内部没有任何操作,所以IDA是无法通过类型传播来得到正确的函数参数和数据类型的,默认,IDA会生成如下函数:

为此我们来修正下它,参看下调用处的汇编

[cpp]  view plain  copy 008 sub     esp, 8          ; 参看标识1可知此处开始压参,此处压了8,结合下面,为double   010 fld     ds:dbl_4020E8   010 fstp    [esp+0Ch+var_C]   010 push    1               ; 此处压最左参数int   014 call    sub_401000      ; 此处堆栈是偏移0x14,0x14-0xc = 0x8处,标识1   014 add     esp, 0Ch        ; 加0xc!说明是c调用,调用者平衡   从而,使用Edit▶Functions▶Set Function Type命令,或者在函数名称上右击鼠标并在上下文菜单中选择SetFunction Type(或使用热键Y)来设置函数的类型

F5反汇编一下:

最后,IDA会向新修改的函数的所有调用方传播这些信息,从而改进对此处显示的所有相关函数调用的附加说明

2.创建数组结构 示例1.局部数组

先逐步分析:

修正函数

对应逆向代码如下

[cpp]  view plain  copy void *sub_401000()   {     void *result; // eax@1     int i; // [sp+0h] [bp-194h]@1     int array_int[100]; // [sp+4h] [bp-190h]@1        array_int[0] = 0;     result = memset(&array_int[1], 0, 0x18Cu);     array_int[20] = 15;     for ( i = 0; i Setup Data Types选中项来决定轮换),即确认数组中元素的大小

2.然后通过Edit▶Array命令打开如图所示的“创建数组”对话框

•Array element Width(数组元素宽度)。这个值表示各数组元素的大小(这里为1字节),它由你在打开对话框时选择的数据值的大小决定。 

 •Maximum possible size(最大可能大小)。这个值由自动计算得出,它决定在遇到另一个已定义的数据项之前,可包含在数组中的元素(不是字节)的最大数目。你可以指定一个更大的值,但这需要随后的数据项为未定义数据项,以将它们吸收到数组中。

•Number of elements(元素数量)。你可以在这里指定数组的具体大小。数组占用的总字节数可通过“元素数量×数组元素宽度”计算得出。

•Items on a line(行中的项目)。指定在每个反汇编行显示的元素的数量。通过它可以减少显示数组所需的空间。

•Element width(元素宽度)。这个值仅用于格式化。当一行显示多个项目时,它控制列宽。

•Use“dup”construct(使用重复结构)。这个选项可将相同的数据值合并起来,用一个重复说明符组合成一项。  

•Signed elements(有符号元素)。表示将数据显示为有符号还是无符号的值。  

•Display indexes(显示索引)。使数组索引以常规注释的形式显示。如果你需要定位大型数组中的特定数据,可以使用这个选项。选择该选项还将启用Indexes单选按钮,这样就可以选择每个索引值的显示格式。  

 •Create as array(创建为数组)。不选择这个选项似乎有悖于本对话框的目的,该选项默认处于选中状态。如果你只希望指定一定数量的连续项目,而不是将它们组合成一个数组,即可取消该选项。

•Items on a line(行中的项目)。指定在每个反汇编行显示的元素的数量。通过它可以减少显示数组所需的空间。•Array element Width(数组元素宽度)。这个值表示各数组元素的大小(这里为1字节),它由你在打开对话框时选择的数据值的大小决定。   •Maximum possible size(最大可能大小)。这个值由自动计算得出,它决定在遇到另一个已定义的数据项之前,可包含在数组中的元素(不是字节)的最大数目。你可以指定一个更大的值,但这需要随后的数据项为未定义数据项,以将它们吸收到数组中。   •Number of elements(元素数量)。你可以在这里指定数组的具体大小。数组占用的总字节数可通过“元素数量×数组元素宽度”计算得出。基于IDA分配的哑名,我们知道,全局数组由从地址0040B720开始的12个字节组成。在编译过程中,编译器使用了固定索引(0、1、2)来计算数组中对应元素的具体地址(0040B720、0040B724和0040B728)

 示例3.栈分配的数组

 编译器几乎以完全相同的方式处理栈分配的数组和全局分配的数组。

[cpp]  view plain  copy sub_401000 proc near      var_10= dword ptr -10h   var_C= dword ptr -0Ch   var_8= dword ptr -8   var_4= dword ptr -4      push    ebp   mov     ebp, esp   sub     esp, 10h   mov     [ebp+var_10], 2   mov     [ebp+var_C], 10   mov     [ebp+var_8], 20   mov     [ebp+var_4], 30   mov     eax, [ebp+var_10]   mov     [ebp+eax*4+var_C], 40   mov     esp, ebp   pop     ebp   retn   先逐步分析:

[cpp]  view plain  copy mov     [ebp+eax*4+var_C], 40 ; 暗示var_C为int数组   双击var_C,使用array分配:

[cpp]  view plain  copy push    ebp   mov     ebp, esp   sub     esp, 10h   mov     [ebp+var_10], 2   mov     [ebp+var_C], 10   mov     [ebp+var_C+4], 20   mov     [ebp+var_C+8], 30   mov     eax, [ebp+var_10]   mov     [ebp+eax*4+var_C], 40 ; 暗示var_C为int数组   其代码如下:

[cpp]  view plain  copy int L_array[3];   int idx = 2;   L_array[0] = 10;   L_array[1] = 20;   L_array[2] = 30;   L_array[idx] = 40;   示例4.堆分配的数组 处理堆分配的数组的主要区别在于,它必须根据内存分配函数返回的地址值,生成对数组的所有引用 [cpp]  view plain  copy push    ebp   mov     ebp, esp   sub     esp, 0Ch   push    0Ch             ; unsigned int   call    ??2@YAPAXI@Z    ; operator new(uint)   add     esp, 4   mov     [ebp+var_C], eax   mov     eax, [ebp+var_C]   mov     [ebp+var_8], eax   mov     [ebp+var_4], 2   mov     ecx, [ebp+var_8]   mov     dword ptr [ecx], 0Ah   mov     edx, [ebp+var_8]   mov     dword ptr [edx+4], 14h   mov     eax, [ebp+var_8]   mov     dword ptr [eax+8], 1Eh   mov     ecx, [ebp+var_4]   mov     edx, [ebp+var_8]   mov     dword ptr [edx+ecx*4], 28h   mov     esp, ebp   pop     ebp   retn  

先逐步分析:

[cpp]  view plain  copy call    ??2@YAPAXI@Z    ; operator new(uint)   add     esp, 4   mov     [ebp+var_C], eax ; eax保存了new的堆指针   mov     eax, [ebp+var_C]   mov     [ebp+var_8], eax ; var_8保存了new的堆指针   mov     [ebp+var_4], 2  ; var_4 = 2   mov     ecx, [ebp+var_8] ; ecx保存了new的堆指针   mov     dword ptr [ecx], 0Ah ; new的堆指针(int[0]=0a)   mov     edx, [ebp+var_8] ; edx保存了new的堆指针   mov     dword ptr [edx+4], 14h ; int[1]=0x14   mov     eax, [ebp+var_8] ; eax保存了new的堆指针   mov     dword ptr [eax+8], 1Eh ; int[2]=0x1e   mov     ecx, [ebp+var_4] ; ecx=2   mov     edx, [ebp+var_8] ; edx保存了new的堆指针   mov     dword ptr [edx+ecx*4], 28h ; int[2]=0x28   其代码如下:

[cpp]  view plain  copy int *heap_array = new int[3];       int idx = 2;       heap_array[0] = 10;       heap_array[1] = 20;       heap_array[2] = 30;       heap_array[idx] = 40;  


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3